home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / Macintosh Sample Code / SC.023.FracApp 2.0 / UFracApp.p < prev    next >
Encoding:
Text File  |  1990-04-30  |  35.5 KB  |  775 lines  |  [TEXT/MPS ]

  1. {[j=20/53/1$]}
  2.  
  3. UNIT UFracApp;
  4.  
  5. {-------------------------------------------------------------------------------------------
  6.  
  7.     Program:    FracApp 2.0
  8.     Unit:        UFracApp
  9.     File:        UFracApp.p
  10.     Includes:    UFracApp.inc1.p
  11.  
  12.     by Keith Rollin & Bo3b Johnson
  13.     of Apple Macintosh Developer Technical Support
  14.  
  15.     Copyright © 1988-1990 Apple Computer, Inc.
  16.     All rights reserved.
  17.  
  18. --------------------------------------------------------------------------------------------
  19.  
  20.     Main unit for FracApp 2.0. It defines the following classes:
  21.  
  22.         TFracAppApplication - Handles creation of documents, Windows menu, idle time
  23.             munging, and multipaging.
  24.         TPICTDocument - Sort of a generic PICT handling document. It’s supposed to be
  25.             all-purpose, but I admit that it was created with FracApp in mind, so you
  26.             might not be able to just drop it into your application without some changes.
  27.             Anyway, it knows how to read and write a PICT file. All you have to do is
  28.             sub-class it and override the DoDrawPicture method to do the actual imaging.
  29.             You might also want to override DoRead and DoWrite to deal with any PICT
  30.             header information you may have.
  31.         TFracAppDocument - Sub-Class of TPICTDocument. Reads and writes PICT header
  32.             information that describes the fractals we make. Also manages the FracApp
  33.             engines we use to create the fractals in the first place. Finally, it acts as
  34.             a go-between for the TFracAppView, and the engine that is generating our
  35.             data.
  36.         TFracAppWindow - Calls the application to tell it when windows are being added
  37.             or removed. This is so we can have a Windows menu (very necessary when you
  38.             have an application that makes all its windows as large as your screen.) Also
  39.             repositions items in the info bars when the window changes size. This
  40.             wouldn’t be necessary if MacApp had location determiners to go along with its
  41.             size determiners.
  42.         TFracAppView - CopyBits stuff from our offscreen pixmap to the window. Handles
  43.             creation of new documents based on the selection, as the View keeps track of
  44.             the selection rectangle. Also deals with highlighting the selection, and
  45.             writing that selection to scrap on a Copy.
  46.         TFracAppEngine - Base class for a fractal generating engine. Again, this was
  47.             myopically designed with FracApp in mind, so you may have a chore of adopting
  48.             it for Fractals other than the Mandelbrot set. It provides a core routine for
  49.             calculating the value of a pixel, and defines methods you should override.
  50.             The methods define what should be done at Idle time, and how to read and
  51.             write Engine specific data to disk.
  52.         TNormalFracAppEngine - Calculates the entire document pixel-by-pixel.
  53.         TFastFracAppEngine - Calculates the Mandelbrot set using the Mariani/Silver
  54.             algorithm. This algorithm assumes that the content of any area that is
  55.             bounded by a single color is the same color. This algorithm recursively
  56.             divides the document up into 4 parts, and examines the borders of each
  57.             rectangle. If the border is all the same color, then the entire rectangle is
  58.             filled with that color, and we go to the next rectangle. If the border colors
  59.             are not all the same, then THAT rectangle is quartered, and we do the process
  60.             again.
  61.  
  62. --------------------------------------------------------------------------------------------}
  63.  
  64.     INTERFACE
  65.  
  66.         USES UMacApp, UDialog, UPrinting, PaletteMgr, Resources, ToolUtils, Packages,
  67.              QDOffscreen, SANE, Timer, UOffscreen, UAreaSelector, URectStack;
  68.  
  69.         CONST
  70.  
  71.             { Constants used for identification }
  72.  
  73.             kSignature            = 'Arfz';            { Application signature }
  74.             kHeaderID            = $4641;            { Header ID = ‘FA’ for FracApp }
  75.             kFileType            = 'PICT';            { File-type code used for document files
  76.                                                      created by this application }
  77.  
  78.             kSelPattern         = 128;                { pattern resource Id. This is in the public section
  79.             as both UFracApp and UAreaSelector access the pattern. }
  80.  
  81.         TYPE
  82.  
  83.         { The following record is used to define data in two places. First of all, it
  84.           is included in the set of data that defines a fractal document, and is saved
  85.           to disk in the PICT header part. It is also used for a global variable that
  86.           we use when creating a new document during a zoom or multipage operation; it
  87.           contains the minimum amount of information for creating a new fractal
  88.           document. }
  89.  
  90.             PageRecord            = RECORD
  91.                 RealMin:            Extended;        { 12 These are valid for any doc }
  92.                 RealMax:            Extended;        { 12 }
  93.                 ImagMin:            Extended;        { 12 }
  94.                 ImagMax:            Extended;        { 12 }
  95.                 multiPaging:        Boolean;        {  2 Whether or not we are multipaging }
  96.                 currentH:            Integer;        {  2 only make sense if above is TRUE }
  97.                 currentV:            Integer;        {  2 These two hold the current page }
  98.                 maxH:                Integer;        {  2 These two hold the range of pages }
  99.                 maxV:                Integer;        {  2 }
  100.                 END;                                { 58 for PageRecord }
  101.  
  102.         { The header record for each of the files saved by FracApp. This header
  103.           includes the pertinent data that allows a fractal to be restarted, as well as
  104.           displayed on the screen. }
  105.  
  106.             FracRecord            = RECORD
  107.                 fType:                OSType;         {  4 set as ‘Arfz’ for these documents. }
  108.                 hdrId:                Integer;        {  2 ‘FA’ - FracApp header ID. }
  109.                 version:            Integer;        {  2 file version decides type of file. }
  110.                 done:                Boolean;        {  2 if the fractal is finished or not. }
  111.                 elapsed:            Longint;        {  4 time in msec taken so far. }
  112.                 startingTime:        Longint;        {  4 result from GetDateTime (secs) }
  113.                 endingTime:         Longint;        {  4 result from GetDateTime (secs) }
  114.                 areaComplete:        Longint;        {  4 amount of the fractal completed }
  115.                 use32BitCQD:        Boolean;        {  2 Kind of offworlder to use. }
  116.                 pages:                PageRecord;     { 58 holds info on the current page }
  117.                 deltaP:             Extended;        { 12 horz step size in fractal space. }
  118.                 deltaQ:             Extended;        { 12 vert step size in fractal space. }
  119.                 plotWidth:            Longint;        {  4 width of fractal area in pixels. }
  120.                 plotHeight:         Longint;        {  4 height of fractal area in pixels. }
  121.                 calcRect:            Rect;            {  8 rectangle surrounding the window it
  122.                                                          was built for. }
  123.                 END;                                {126 FracRecord. }
  124.  
  125.             {-------------------------------  Application  -------------------------------}
  126.  
  127.             TFracAppApplication = OBJECT (TApplication)
  128.  
  129.                 fWindowList:        TList;            { Private - Holds the list of windows
  130.                                                      in the order in which they were
  131.                                                      created. Maintained by
  132.                                                      InstallWindowMenuItem }
  133.  
  134.                 PROCEDURE TFracAppApplication.IFracAppApplication(itsMainFileType: OSType);
  135.                 { Initializes the application and globals. Called by the main application when
  136.                   the applicaton object is created. }
  137.  
  138.                 PROCEDURE TFracAppApplication.AutoSaveThisGuy(doneDoc: TFracAppDocument);
  139.                 { Handy dude for saving and closing a document without human accompaniament.
  140.                   We use this when creating a series of documents, possibly at night when
  141.                   no one is around. Called by TFracAppApplication.DoIdle when a document
  142.                   signals that it’s done. }
  143.  
  144.                 PROCEDURE TFracAppApplication.BuildWindowsMenu;
  145.                 { Called by TFracAppApplication.DoSetupMenus whenever our Windows menu changes
  146.                   and needs to be rebuilt. }
  147.  
  148.                 PROCEDURE TFracAppApplication.Close; OVERRIDE;
  149.                 { Called by MacApp when the user selects Quit. Tear down stuff when the program
  150.                   is about to quit. Most importantly, we have to turn off the time manager
  151.                   routines. Done here rather than in TApplication.Free, as .Free rarely gets
  152.                   called. It’s up to the main application to do that, and we’ve never
  153.                   recommended that that be done. }
  154.  
  155.                 PROCEDURE TFracAppApplication.CreateManyColors;
  156.                 { Called by IFracAppApplication to initialize our color Palettes. }
  157.  
  158.                 FUNCTION TFracAppApplication.DoIdle(Phase: IdlePhase): Boolean; OVERRIDE;
  159.                 { Called by MacApp to perform Idle time processing for the application.  This
  160.                   will do the fractal calculation during the idle times. Also allows the
  161.                   topmost document a chance to to color animation. }
  162.  
  163.                 FUNCTION TFracAppApplication.DoMakeDocument(itsCmdNumber: CmdNumber):
  164.                                                             TDocument; OVERRIDE;
  165.                 { Launches a TFracAppDocument; called when application’s icon is opened, or
  166.                   when New, New From Selection, New MultiPage, or Open is requested by the
  167.                   user. Every application which uses documents MUST override this method. }
  168.  
  169.                 FUNCTION TFracAppApplication.DoMenuCommand(aCmdNumber: CmdNumber): TCommand;
  170.                     OVERRIDE;
  171.                 { Called by MacApp when a menu item has been chosen. Handles executing Animate,
  172.                   32-Bit Color QuickDraw, and 300 dpi options. }
  173.  
  174.                 PROCEDURE TFracAppApplication.DoSetupMenus; OVERRIDE;
  175.                 { Called by MacApp when the user clicks on the menu. Handles the en/disabling
  176.                   of Animate, 32-Bit Color QuickDraw, and 300 dpi options. }
  177.  
  178.                 PROCEDURE TFracAppApplication.DoShowAboutApp; OVERRIDE;
  179.                 { Shows the About Box. With MacApp 2.0, this method is called from a
  180.                   TAboutCommand when the user selects the About… item. }
  181.  
  182.                 PROCEDURE TFracAppApplication.DoWindowsCommand(aCmdNumber: CmdNumber);
  183.                 { Sub-method to handle selections in the Windows menu. Called by
  184.                   TFracAppApplication.DoMenuCommand. }
  185.  
  186.                 PROCEDURE TFracAppApplication.InstallWindowMenuItem(window: TWindow;
  187.                                                                     install: Boolean);
  188.                 { Called by our TFracAppWindow object when it shows or hides itself. This
  189.                   method keeps track of the window in a list, which is used for building
  190.                   our Windows menu. }
  191.  
  192.                 PROCEDURE TFracAppApplication.MakeNewGibbleyFromGPageRecord;
  193.                 { Handy routine for when we are multipaging. It is called from our DoIdle
  194.                   method to create a new document based on the state of the last one. }
  195.  
  196.                 PROCEDURE TFracAppApplication.Fields(PROCEDURE
  197.                                                      DoToField(fieldName: Str255;
  198.                                                                fieldAddr: Ptr;
  199.                                                                fieldType: Integer));
  200.                     OVERRIDE;
  201.  
  202.                 END;                                { TFracAppApplication }
  203.  
  204.             {-------------------------------  Document    -------------------------------}
  205.  
  206.             TPICTDocument        = OBJECT (TDocument)
  207.  
  208.                 PROCEDURE TPICTDocument.IPICTDocument;
  209.                 { Init routine for the document. For TPICTDocument, it does nothing except call
  210.                   IDocument. }
  211.  
  212.                 PROCEDURE TPICTDocument.DoDrawPicture;
  213.                 { DoNeedDiskSpace and DoWrite need some way to image the picture. A
  214.                   TPICTDocument doesn’t have any idea how the data is being kept, so it doesn’t
  215.                   know how to do the imaging. Therefore, we have this DoDrawPicture method that
  216.                   should be overridden by subclasses. It is the subclasses that know how the
  217.                   data is stored, and so they can image it. By default, this routine does
  218.                   nothing but complain. }
  219.  
  220.                 PROCEDURE TPICTDocument.DoNeedDiskSpace(VAR dataForkBytes,
  221.                                                         rsrcForkBytes: Longint); OVERRIDE;
  222.                 { Called by MacApp when preparing to write out a disk file. Finds out the
  223.                   entire size of the object to be saved into the file so that the correct
  224.                   amount of disk space can be used. For a TPICTDocument, this is the size of
  225.                   the PICT, plus 512 bytes for the header. }
  226.  
  227.                 PROCEDURE TPICTDocument.DoRead(aRefNum: Integer; rsrcExists,
  228.                                                forPrinting: Boolean); OVERRIDE;
  229.                 { Called by MacApp to read the data from the data fork of the file. Stows it
  230.                   into the document’s bitMap. This bitmap should be setup by the subclass in
  231.                   its DoRead method before calling this INHERITED method. In other words, this
  232.                   just draws into the current port and device. }
  233.  
  234.                 PROCEDURE TPICTDocument.DoWrite(aRefNum: Integer; makingCopy: Boolean); OVERRIDE;
  235.                 { Called by MacApp to write out the document’s data. Converts the data in the
  236.                   document’s port into a PICT, then writes that block out to the file, making
  237.                   it into a standard PICT file. It does this with the help of its humbler
  238.                   servant, TPICTDocument.DoDrawPicture. }
  239.  
  240.                 PROCEDURE TPICTDocument.SetRWGrafProcs(VAR oldProcs: QDProcsPtr;
  241.                                                        VAR newProcs: CQDProcs; readProc,
  242.                                                        writeProc: ProcPtr);
  243.                 { Common routine to set the current port’s grafprocs for reading and writing.
  244.                   It gets called by our DoRead and DoWriter overrides to that we can read
  245.                   and write PICTs without causing a big memory hit. }
  246.  
  247.                 PROCEDURE TPICTDocument.Fields(PROCEDURE
  248.                                                DoToField(fieldName: Str255; fieldAddr: Ptr;
  249.                                                          fieldType: Integer)); OVERRIDE;
  250.  
  251.                 END;
  252.  
  253.             TFracAppDocument    = OBJECT (TPICTDocument)
  254.  
  255.                 fFracHeader:        FracRecord;     { Global state of any fractal. It can be
  256.                                                      accessed with the following methods:
  257.                                                      GetDone, GetFracHeader, GetPlotHeight,
  258.                                                      GetPlotWidth }
  259.                 fFracAppEngine:     TFracAppEngine; { Private - Used by CalcTown, DoRead, and
  260.                                                      DoWrite }
  261.                 fFracAppWindow:     TFracAppWindow; { Private - Used to animate the window’s
  262.                                                      palettes. }
  263.                 fOffWorlder:        TOffscreen;     { Private - Object that handle offscreen
  264.                                                      management. }
  265.                 fStartupMode:        CmdNumber;        { Private - Used in DoInitialState to set
  266.                                                      variables that are different depending
  267.                                                      on whether we are multipaging or not,
  268.                                                      or if we are creating this document
  269.                                                      afresh or based on the selection of
  270.                                                      another document. }
  271.  
  272.                 PROCEDURE TFracAppDocument.IFracAppDocument(use32BitCQD: Boolean;
  273.                                                             startupMode: CmdNumber);
  274.                 { Init routine for the document. Called when the new document is created in
  275.                   TFracAppApplication.DoMakeDocument. Sets up the object, then the fractal
  276.                   default state. }
  277.  
  278.                 PROCEDURE TFracAppDocument.Free; OVERRIDE;
  279.                 { Free method for our document.  It calls FreeData to dispose the data block of
  280.                   the picture data that was read in from the disk, and kills the offscreen
  281.                   stuff. }
  282.  
  283.                 PROCEDURE TFracAppDocument.AnimateColors;
  284.                 { Called by the application at Idle time to do the palette animation. }
  285.  
  286.                 PROCEDURE TFracAppDocument.BumpAreaComplete(areaAmount: Longint);
  287.                 { Adds “areaAmount” to the areaComplete field. We keep track of this stuff so
  288.                   that we can display the percentage complete. This is my own method that the
  289.                   TFracAppEngines call when they’ve updated a new area of the fractal. }
  290.  
  291.                 PROCEDURE TFracAppDocument.BumpChangeCount;
  292.                 { Increments the fChangeCount field. This is my own method that the
  293.                   TFracAppEngines call when they’ve updated a new area of the fractal. }
  294.  
  295.                 PROCEDURE TFracAppDocument.BumpCalculationTime(elapsedAmount: Longint);
  296.                 { Increments the elapsedTime field and updates the window display. Called
  297.                   by the document idling routine: CalcTown. }
  298.  
  299.                 FUNCTION TFracAppDocument.CalcTown: Boolean;
  300.                 { Document’s idling routine. Called by TFracAppApplication.DoIdle when it’s
  301.                   this document’s turn to calculate part of itself. Takes care of calling the
  302.                   TFracAppEngine, and updating the window timer displays. }
  303.  
  304.                 PROCEDURE TFracAppDocument.DoDrawPicture; OVERRIDE;
  305.                 { Called by TPICTDocument.DoRead and DoWrite. Images the picture for saving to
  306.                   disk. Just calls Copybits. }
  307.  
  308.                 PROCEDURE TFracAppDocument.DoInitialState; OVERRIDE;
  309.                 { Called by MacApp if we are making a new document (as opposed to reading one
  310.                   from disk). Does the work for a New operation, where we start with a new
  311.                   fractal that doesn’t have any stored data. }
  312.  
  313.                 PROCEDURE TFracAppDocument.DoMakeViews(forPrinting: Boolean); OVERRIDE;
  314.                 { Called when launching a new document, be it newly created or being read from
  315.                   disk. Launches the view which is seen in the document’s window.  Every
  316.                   document which has any screen display or which can be printed MUST override
  317.                   this method. }
  318.  
  319.                 FUNCTION TFracAppDocument.DoMenuCommand(aCmdNumber: CmdNumber): TCommand;
  320.                     OVERRIDE;
  321.                 { Called by MacApp when a menu item has been chosen. Handles the Copy menu
  322.                   item, as well as everything in the Zoomy menu }
  323.  
  324.                 PROCEDURE TFracAppDocument.DoNeedDiskSpace(VAR dataForkBytes,
  325.                                                            rsrcForkBytes: Longint); OVERRIDE
  326.                     ;
  327.                 { Called by MacApp when preparing to save a document to disk. This override
  328.                   doesn’t do any calculations itself, but it does prepare the offscreen world
  329.                   before we call the INHERITED method. }
  330.  
  331.                 PROCEDURE TFracAppDocument.DoRead(aRefNum: Integer; rsrcExists,
  332.                                                   forPrinting: Boolean); OVERRIDE;
  333.                 { Called by MacApp to read the data from the data fork of the file. Sets up the
  334.                   offscreen world so that we can call the INHERITED method to do the reading of
  335.                   the PICT. Also resets the vars in the document object to match the saved
  336.                   values from the header. }
  337.  
  338.                 PROCEDURE TFracAppDocument.DoSetupMenus; OVERRIDE;
  339.                 { Called by MacApp when the user clicks on the menu. Handles the Copy menu
  340.                   item, as well as everything in the “Animate” menu. The “Animate” menu is only
  341.                   enabled if we have 32-bit Color QuickDraw. }
  342.  
  343.                 PROCEDURE TFracAppDocument.DoWrite(aRefNum: Integer; makingCopy: Boolean); OVERRIDE;
  344.                 { Called by MacApp to write out the document’s data. Sets up the offscreen
  345.                   world, and calls the INHERITED method to actually write out the PICT. Also
  346.                   writes out the standard FracHeader, and calls the engine’s DoWrite method to
  347.                   have it write out anything it needs. }
  348.  
  349.                 PROCEDURE TFracAppDocument.FreeData; OVERRIDE;
  350.                 { Free method usually used for Revert operation, kept here to show the normal
  351.                   Free approach. }
  352.  
  353.                 FUNCTION TFracAppDocument.GetDone: Boolean;
  354.                 { Returns the fFracHeader.done field. Called by various FracApp routines to see
  355.                   if this document needs any calculation time. }
  356.  
  357.                 FUNCTION TFracAppDocument.GetFracHeader: FracRecord;
  358.                 { Returns a copy of the fFracHeader field. This is an easy way for the
  359.                   TFracAppEngine to get a lot of working values it needs. }
  360.  
  361.                 FUNCTION TFracAppDocument.GetFracPort: CGrafPtr;
  362.                 { Returns the offscreen port. Used by the TFracAppView when updating the screen. }
  363.  
  364.                 FUNCTION TFracAppDocument.GetOffPixBase: Ptr;
  365.                 { Returns the pointer to the bits for the offscreen port. Called by the
  366.                   TFracAppEngine when doing its own version of GetCPixel. }
  367.  
  368.                 FUNCTION TFracAppDocument.GetPlotHeight: Longint;
  369.                 { Returns fFracHeader.plotHeight. Called by TAreaSelector so that it knows what
  370.                   dimensions the document is, so that it can etch a proportional selection
  371.                   rectangle. }
  372.  
  373.                 FUNCTION TFracAppDocument.GetPlotWidth: Longint;
  374.                 { Returns fFracHeader.plotWidth. Called by TAreaSelector so that it knows what
  375.                   dimensions the document is, so that it can etch a proportional selection
  376.                   rectangle. }
  377.  
  378.                 FUNCTION TFracAppDocument.IsMultiPaging: Boolean;
  379.                 { Return TRUE if this document is one in a series of multi-paged documents. }
  380.  
  381.                 PROCEDURE TFracAppDocument.JumblePalette;
  382.                 { Jumbles up the palette so that we get a nice banding effect. Called by
  383.                   TFracAppDocument.DoMenuCommand when the user selects the Jump Palette menu
  384.                   item. }
  385.  
  386.                 PROCEDURE TFracAppDocument.LockThePixels(lockIt: Boolean);
  387.                 { Called by the TFracAppView before it does any CopyBits operations. This is
  388.                   so the View only needs to know about the TFracAppDocument; it never needs
  389.                   to know that a TOffScreen object exists. }
  390.  
  391.                 FUNCTION TFracAppDocument.MakeFracAppEngine(version: Integer): TFracAppEngine
  392.                                                             ;
  393.                 { Handy utility for making a TFracAppEngine. Makes a different kind depending
  394.                   on what ‘version’ is set to. Called by TFracAppDocument.DoRead and
  395.                   DoInitialState. }
  396.  
  397.                 FUNCTION TFracAppDocument.MakeOffWorlder(use32BitCQD: Boolean;
  398.                                                          bounds: Rect): TOffscreen;
  399.                 { Handy utility for making a TOffScreen. Makes a different kind depending on
  400.                   what ‘use32BitCQD’ is set to. Called by TFracAppDocument.DoRead and
  401.                   DoInitialState. }
  402.  
  403.                 PROCEDURE TFracAppDocument.PreDraw;
  404.                 { Called by TFracAppEngine before it images to the offscreen bitmap. This is
  405.                   so the Engine only needs to know about the TFracAppDocument; it never needs
  406.                   to know that a TOffScreen object exists. }
  407.  
  408.                 PROCEDURE TFracAppDocument.PostDraw;
  409.                 { Called by TFracAppEngine when it is all done imaging to the offscreen dude. }
  410.  
  411.                 PROCEDURE TFracAppDocument.ReportRectCompleted(dirtyRect: Rect);
  412.                 { Called by the TFracAppEngine when an area of the fractal has been completed and
  413.                 needs to be copied to the screen. }
  414.  
  415.                 PROCEDURE TFracAppDocument.RestorePalette;
  416.                 { Recovers from the effects of Animating or Jumbling. Called by
  417.                   TFracAppDocument.DoMenuCommand when the user selects “Everything back to
  418.                   Normal”, or turns off “Jumble Palette”. }
  419.  
  420.                 PROCEDURE TFracAppDocument.SetAreaComplete(newComplete: Longint;
  421.                                                            forceUpdate: Boolean);
  422.                 { Updates the areaCompleted field in fFracHeader. Also updates the percentage
  423.                   field in the window. }
  424.  
  425.                 PROCEDURE TFracAppDocument.SetCalculationTime(newElapsed: Longint;
  426.                                                               forceUpdate: Boolean);
  427.                 { Updates the elapsedTime field in fFracHeader. Also updates the calculation time
  428.                   field in the window’s infobar. }
  429.  
  430.                 PROCEDURE TFracAppDocument.SetElapsedTime(forceUpdate: Boolean);
  431.                 { Updates the elapsed time field in the window’s infobar based on the starting
  432.                   and current time. }
  433.  
  434.                 PROCEDURE TFracAppDocument.SetMethodName(forceUpdate: Boolean);
  435.                 { Sets the string that displays the algorithm being used to create the fractal.
  436.                   Called by TFracAppDocument.DoMakeViews when the document is being created. }
  437.  
  438.                 PROCEDURE TFracAppDocument.SetVersion(version: Integer);
  439.                 { Called by the TFracAppEngine when it initializes itself. The engine is
  440.                   responsible for keeping track of what version document is created. Calling
  441.                   SetVersion is its way of informing the document what version it is. }
  442.  
  443.                 PROCEDURE TFracAppDocument.StashSelectedRange;
  444.                 { Called by the routines that handle creating a new document based on the
  445.                   current selection Transfers information relating to the selection on the
  446.                   screen into some global variables. This is so we can create a new document
  447.                   from them. }
  448.  
  449.                 PROCEDURE TFracAppDocument.Fields(PROCEDURE
  450.                                                   DoToField(fieldName: Str255;
  451.                                                             fieldAddr: Ptr;
  452.                                                             fieldType: Integer)); OVERRIDE;
  453.  
  454.                 END;                                { TFracAppDocument }
  455.  
  456.             {-------------------------------  Window  -------------------------------}
  457.  
  458.             TFracAppWindow        = OBJECT (TWindow)
  459.  
  460.                 fFracAppView:        TFracAppView;
  461.                 fCTimeLabelView:    TStaticText;
  462.                 fCTimeView:         TStaticText;
  463.                 fETimeLabelView:    TStaticText;
  464.                 fETimeView:         TStaticText;
  465.                 fMethodNameView:    TStaticText;
  466.                 fPercentView:        TStaticText;
  467.                 fPercentLabelView:    TStaticText;
  468.                 fSingleBarView:        TControl;
  469.  
  470.                 PROCEDURE TFracAppWindow.IRes(itsDocument: TDocument; itsSuperView: TView;
  471.                                               VAR itsParams: Ptr); OVERRIDE;
  472.                 { Initialize our window object. Overridden to set our instance variables to
  473.                   NIL. }
  474.  
  475.                 PROCEDURE TFracAppWindow.AdjustInfoBar(width, height: VCoordinate;
  476.                                                        invalidate: Boolean);
  477.                 { Called by TFracAppWindow.Show and Resize to make sure the items in the
  478.                   infobar and the percentage complete label are all in the right places. }
  479.  
  480.                 FUNCTION TFracAppWindow.GetCTimeView: TStaticText;
  481.                 { Return the “Calculation Time” text item. Called by TFracAppDocument when it
  482.                   needs to update that part of the display. }
  483.  
  484.                 FUNCTION TFracAppWindow.GetETimeView: TStaticText;
  485.                 { Return the “Elapsed Time” text item. Called by TFracAppDocument when it needs
  486.                   to update that part of the display. }
  487.  
  488.                 FUNCTION TFracAppWindow.GetFracAppView: TFracAppView;
  489.                 { Return the main view that displays the fractal. Called by TFracAppDocument
  490.                   when it needs to update that part of the display. }
  491.  
  492.                 FUNCTION TFracAppWindow.GetMethodView: TStaticText;
  493.                 { Return the text item that shows the algorithm being used. Called by
  494.                   TFracAppDocument when it needs to initialize that part of the display. }
  495.  
  496.                 FUNCTION TFracAppWindow.GetPercentView: TStaticText;
  497.                 { Return the “Percentage complete” text item. Called by TFracAppDocument when
  498.                   it needs to update that part of the display. }
  499.  
  500.                 PROCEDURE TFracAppWindow.Open; OVERRIDE;
  501.                 { Called by MacApp when it needs to open a window. We override it here so that
  502.                   we can also call AdjustInfoBar. }
  503.  
  504.                 PROCEDURE TFracAppWindow.Resize(width, height: VCoordinate;
  505.                                                 invalidate: Boolean); OVERRIDE;
  506.                 { Called by MacApp when it needs to resize a window. We override it here so
  507.                   that we can also call AdjustInfoBar. }
  508.  
  509.                 PROCEDURE TFracAppWindow.Show(state, redraw: Boolean); OVERRIDE;
  510.                 { Called by MacApp when it shows or hides a window. Overridden so that we can
  511.                   add or delete ourselves from the Windows menu. }
  512.  
  513.                 PROCEDURE TFracAppWindow.SetTitle(newTitle: Str255); OVERRIDE;
  514.                 { Overridden so that we can force the Windows menu to be rebuilt if this
  515.                   window’s name changes. This can happen when a document is saved. }
  516.  
  517.                 PROCEDURE TFracAppWindow.Fields(PROCEDURE
  518.                                                 DoToField(fieldName: Str255; fieldAddr: Ptr;
  519.                                                           fieldType: Integer)); OVERRIDE;
  520.  
  521.                 END;
  522.  
  523.             {-------------------------------  View    -------------------------------}
  524.  
  525.             { This object is used to display the elapsed time items, and the percentage
  526.               complete item. I found that with a normal TStaticText item, I got too much
  527.               flashing when I updated the strings. There was too much of a time gap between
  528.               when the old string got erased, and the new one got drawn. I’ve tried to
  529.               minimize that by having MATextbox (which is what ultimately draws the string)
  530.               erase the old text when it draws the new. There is still SOME flicker, but
  531.               not as much as there used to be. }
  532.  
  533.             TNoFlashStaticText    = OBJECT (TStaticText)
  534.  
  535.                 PROCEDURE TNoFlashStaticText.ImageText(text: Ptr;
  536.                                                 Length: LONGINT;
  537.                                                 box: Rect;
  538.                                                 just: INTEGER); OVERRIDE;
  539.                 { Overridden so that it passes the kEraseText parameter to MATextbox. }
  540.  
  541.                 PROCEDURE TNoFlashStaticText.SetText(theText: Str255;
  542.                               redraw: BOOLEAN); OVERRIDE;
  543.                 { Overridden to inhibit erasing the old text before drawing the new. }
  544.  
  545.                 PROCEDURE TNoFlashStaticText.Fields(PROCEDURE
  546.                                                 DoToField(fieldName: Str255; fieldAddr: Ptr;
  547.                                                           fieldType: Integer)); OVERRIDE;
  548.                 END;
  549.  
  550.  
  551.             { This is the object that displays the fractal. Besides having its .Draw method
  552.               overridden so that it can copybits the offscreen image, this View also keeps
  553.               track of the current selection rectangle. Because of this, it also handles
  554.               the menu items that would only be enabled when there is a selection. This
  555.               includes Copy, New From Selection, and New Multi-Page. }
  556.  
  557.             TFracAppView        = OBJECT (TView)
  558.  
  559.                 fFracAppDocument:    TFracAppDocument; { Private - Used to tell the document
  560.                                                        to do whatever is necessary to
  561.                                                        prepare the offscreen for updating of
  562.                                                        the window. Also used to tell the
  563.                                                        document to stash the selected range
  564.                                                        into the global page record. Although
  565.                                                        the view has the selected range, the
  566.                                                        document contains the necessary
  567.                                                        scalinging information. }
  568.                 fSelectionRect:     Rect;            { Rectangle that is current selection.
  569.                                                      You can get/set this rectangle with
  570.                                                      Get/SetSelection. }
  571.  
  572.                 PROCEDURE TFracAppView.IRes(itsDocument: TDocument; itsSuperView: TView;
  573.                                             VAR itsParams: Ptr); OVERRIDE;
  574.                 { Inits the view object itself. Keeps track of the document, and initializes
  575.                 the selection rect to be empty. }
  576.  
  577.                 PROCEDURE TFracAppView.DoHighlightSelection(fromHL, toHL: HLState); OVERRIDE;
  578.                 { Called by MacApp’s updating routines to highlight the current selection
  579.                   rectangle if there is one.  }
  580.  
  581.                 FUNCTION TFracAppView.DoMenuCommand(aCmdNumber: CmdNumber): TCommand;
  582.                     OVERRIDE;
  583.                 { Called by MacApp when a menu item has been chosen. Handle the menu choices
  584.                   for New Fractal out of the File Menu, and the Copy and SelectAll commands
  585.                   from the Edit menu. }
  586.  
  587.                 FUNCTION TFracAppView.DoMouseCommand(VAR theMouse: Point;
  588.                                                      VAR info: EventInfo;
  589.                                                      VAR hysteresis: Point): TCommand;
  590.                     OVERRIDE;
  591.                 { Called by MacApp to handle the mouse events in the view. Needs to do the
  592.                   selection of a new range for the next fractal to be calculated. }
  593.  
  594.                 PROCEDURE TFracAppView.DoSetupMenus; OVERRIDE;
  595.                 { Called by MacApp when the user clicks on the menu. Set up the New Fractal
  596.                   menus choice in Fractal Menu, based on selection. }
  597.  
  598.                 PROCEDURE TFracAppView.Draw(area: Rect); OVERRIDE;
  599.                 { Called by MacApp to draw the view seen in the window. Every nonblank view
  600.                   MUST override this method. }
  601.  
  602.                 PROCEDURE TFracAppView.GetQDExtent(VAR qdExtent: Rect); OVERRIDE;
  603.                 { Overridden so that we can redefine the extent of the view when pasting to
  604.                   the scrap.  Paul Snively Memorial Brace ---> }
  605.  
  606.                 FUNCTION TFracAppView.GetSelection: Rect;
  607.                 { Returns the current selection rectangle. Called by
  608.                   TFracAppDocument.StashSelectedRange to get the information it needs to to
  609.                   help create a new document based on the current selection. }
  610.  
  611.                 FUNCTION TFracAppView.HasSelection: Boolean;
  612.                 { Returns TRUE if there is a selection on the screen. Handy when we are
  613.                 enabling menu items based on whether or not there is a selection. }
  614.  
  615.                 PROCEDURE TFracAppView.InvalidRect(r: Rect); OVERRIDE;
  616.                 { InvalidRect is a TView method that invalidates the specified part of the
  617.                   view. We override it here to add a little optimization. The ToolBox routine
  618.                   InvalRect does not optimize for when the passed rectangle is empty. Neither
  619.                   does MacApp. So we check for that here. }
  620.  
  621.                 PROCEDURE TFracAppView.SetSelection(theSelectionRect: Rect; redraw: Boolean);
  622.                 { Sets and redraws the selection. }
  623.  
  624.                 PROCEDURE TFracAppView.Fields(PROCEDURE
  625.                                               DoToField(fieldName: Str255; fieldAddr: Ptr;
  626.                                                         fieldType: Integer)); OVERRIDE;
  627.  
  628.                 END;                                { TFracAppView }
  629.  
  630.             {-------------------------------  Engine  -------------------------------}
  631.  
  632.             TFracAppEngine        = OBJECT (TObject)
  633.  
  634.                 fFracAppDocument:    TFracAppDocument; { Private - Used to tell the document
  635.                                                        that new parts of the fractal have
  636.                                                        been completed, and that the window
  637.                                                        needs to be updated. }
  638.                 fFracHeaderCopy:    FracRecord;     { Private - Holds a copy of the STATIC
  639.                                                      parts of the FracHeader used by the
  640.                                                      FracAppDocument. }
  641.  
  642.                 PROCEDURE TFracAppEngine.IFracAppEngine(itsDocument: TFracAppDocument);
  643.                 { Inits the engine object itself. Remembers a reference to its document, and
  644.                   makes a working copy of its FracHeader. This is done for speed so that we
  645.                   don’t have to continually query the document for its info. }
  646.  
  647.                 FUNCTION TFracAppEngine.CalcCity: Boolean;
  648.                 { Abstract method for calculating a little bit of the fractal. Called by
  649.                   TFracAppDocument.CalcTown. This one here doesn’t do anything; it is meant to
  650.                   be overridden. }
  651.  
  652.                 PROCEDURE TFracAppEngine.DoRead(aRefNum: Integer; rsrcExists,
  653.                                                 forPrinting: Boolean);
  654.                 { Abstract method for reading what the engine needs from disk. Called by
  655.                   TFracAppDocument.DoRead. This one here doesn’t do anything; it is meant to
  656.                   be overridden. }
  657.  
  658.                 PROCEDURE TFracAppEngine.DoWrite(aRefNum: Integer; makingCopy: Boolean);
  659.                 { Abstract method for writing what the engine needs to disk. Called by
  660.                   TFracAppDocument.DoWrite. This one here doesn’t do anything; it is meant to
  661.                   be overridden. }
  662.  
  663.                 PROCEDURE TFracAppEngine.FAGetCPixel(x, y: Integer; VAR itsRGB: RGBColor);
  664.                 { Normal Color QuickDraw has an annoying habit of hiding and showing the cursor
  665.                   when calling GetCPixel -- even for an offscreen pixmap. The bug has been
  666.                   fixed in 32-bit color QuickDraw. This method checks to see what system we are
  667.                   running under. If GetCPixel is OK, we call it. Otherwise, we do it by hand. }
  668.  
  669.                 PROCEDURE TFracAppEngine.GoFigger(x, y, Po, Qo: Extended; M, K: Integer; VAR kol: Integer);
  670.                 { Heart and soul of the program. Called by the CalcCity routines to calculate
  671.                   the color of the specified point. This method is actually implemented in
  672.                   assembly. }
  673.  
  674.                 PROCEDURE TFracAppEngine.ReportRectCompleted(dirtyRect: Rect);
  675.                 { Bottleneck used by CalcCity to inform the document that part of the fractal
  676.                   has been freshly calculated and needs to be copied to the screen. }
  677.  
  678.                 PROCEDURE TFracAppEngine.PixWhap(col, row: Integer; VAR itsRect: Rect;
  679.                                                  VAR itsRGB: RGBColor);
  680.                 { Called by the engine’s CalcCity method. Given a point, figure out its color
  681.                   and plot it. Also returns the actual rectangle used for plotting the thing,
  682.                   and the color used. }
  683.  
  684.                 PROCEDURE TFracAppEngine.Fields(PROCEDURE
  685.                                                 DoToField(fieldName: Str255; fieldAddr: Ptr;
  686.                                                           fieldType: Integer)); OVERRIDE;
  687.  
  688.                 END;
  689.  
  690.             TNormalFracAppEngine = OBJECT (TFracAppEngine)
  691.  
  692.                 fCurrentLocation:    Point;            { Private - holds current positon of the
  693.                                                      “pen”. }
  694.  
  695.                 PROCEDURE TNormalFracAppEngine.INormalFracAppEngine(itsDocument:
  696.                                                                     TFracAppDocument);
  697.                 { Initializes the TNormalFracAppEngine, as well as its superclass. Tells the
  698.                   document its version number, and initializes the pen to (0,0). }
  699.  
  700.                 FUNCTION TNormalFracAppEngine.CalcCity: Boolean; OVERRIDE;
  701.                 { Calculates the fractal one pixel at a time. If we’ve calculated a whole row,
  702.                   tell the document so that it can copy it to the screen. }
  703.  
  704.                 PROCEDURE TNormalFracAppEngine.DoRead(aRefNum: Integer; rsrcExists,
  705.                                                       forPrinting: Boolean); OVERRIDE;
  706.                 { Called by TFracAppDocument.DoRead. Reads fCurrentLocation from disk. }
  707.  
  708.                 PROCEDURE TNormalFracAppEngine.DoWrite(aRefNum: Integer;
  709.                                                        makingCopy: Boolean); OVERRIDE;
  710.                 { Called by TFracAppDocument.DoWrite. Writes fCurrentLocation to disk. }
  711.  
  712.                 PROCEDURE TNormalFracAppEngine.Fields(PROCEDURE
  713.                                                       DoToField(fieldName: Str255;
  714.                                                                 fieldAddr: Ptr;
  715.                                                                 fieldType: Integer));
  716.                     OVERRIDE;
  717.  
  718.                 END;
  719.  
  720.             TFastFracAppEngine    = OBJECT (TFracAppEngine)
  721.  
  722.                 fRectStack:         TRectStack;     { Private - maintains the areas of the
  723.                                                      document we need to still calculate. }
  724.  
  725.                 PROCEDURE TFastFracAppEngine.IFastFracAppEngine(itsDocument: TFracAppDocument
  726.                                                                 );
  727.                 { Initializes the TFastFracAppEngine, as well as its superclass. Tells the
  728.                   document its version number, creates a TRectStack, and seeds it with 4
  729.                   starting rectangles. }
  730.  
  731.                 PROCEDURE TFastFracAppEngine.Free; OVERRIDE;
  732.                 { Frees fRectStack. }
  733.  
  734.                 FUNCTION TFastFracAppEngine.CalcCity: Boolean; OVERRIDE;
  735.                 { Calculates the fractal using the divide and conquer method. }
  736.  
  737.                 PROCEDURE TFastFracAppEngine.DivideAndConquer(r: Rect);
  738.                 { Takes a rectangle, quarters it, and pushes it on the rect stack. Called by
  739.                   CalcCity when it finds a rectangle whose border is not all the same color. }
  740.  
  741.                 PROCEDURE TFastFracAppEngine.DoRead(aRefNum: Integer; rsrcExists,
  742.                                                     forPrinting: Boolean); OVERRIDE;
  743.                 { Called by TFracAppDocument.DoRead. Reads the rect stack from disk. }
  744.  
  745.                 PROCEDURE TFastFracAppEngine.DoWrite(aRefNum: Integer;
  746.                     makingCopy: Boolean); OVERRIDE;
  747.                 { Called by TFracAppDocument.DoWrite. Writes the rect stack to disk. }
  748.  
  749.                 PROCEDURE TFastFracAppEngine.ReportRectCompleted(dirtyRect: Rect); OVERRIDE;
  750.                 { Bottleneck used by CalcCity to inform the document that part of the fractal
  751.                   has been freshly calculated and needs to be copied to the screen. We override
  752.                   it here to fix up the rectangle. Our rectangles are chosen so that there is a
  753.                   little bit of overlap between them and the rects next to them. We have to get
  754.                   rid of that overlap so that updating is more efficient, and so that our
  755.                   “areaCompleted” running total is accurate. }
  756.  
  757.                 PROCEDURE TFastFracAppEngine.Fields(PROCEDURE
  758.                                                     DoToField(fieldName: Str255;
  759.                                                               fieldAddr: Ptr;
  760.                                                               fieldType: Integer)); OVERRIDE
  761.                     ;
  762.  
  763.                 END;
  764.  
  765. {$IFC NOT qPerform}
  766.         VAR
  767.             gCounter:            Longint;
  768. {$ENDC}
  769.  
  770.     IMPLEMENTATION
  771.  
  772. {$I UFracApp.inc1.p}
  773.  
  774. END.
  775.